/**
 * 处理排单类
 */
class assignRoute
{
     static getInstance()
     {
         if(!assignRoute.instance)
         {
             assignRoute.instance = new assignRoute();
         }
         return assignRoute.instance;
     }
    render(){
            if(this.allRequestIsSuccess())
            {
                let source=$('#route-list-template').html();
                let template = Handlebars.compile(source);
                $('#route-list').html(template({data:this.getRouters()}));
                CONFIG.updateRouterTemplateIntervale = setTimeout(()=>{
                    assignRoute.getInstance().render();
                },1500);
            }else{
                CONFIG.updateRouterTemplateIntervale = setTimeout(()=>{
                    assignRoute.getInstance().render();
                },1500);
            }


    }

    /**
     * 获取每条路由
     * @returns {Array}
     */
    getRouters()
    {
        let data = [];
        let routers = OBJECT.directionsDisplay;
        for( let key in routers ) {
            let t={};
            let distanceAndTime={};
            distanceAndTime = this.calcDistanceAndTimes(key)
            t.vehicleId = this.getVehicleName(key) || 'UnAssign';
            t.driver = this.getDriverName(key) || 'UnAssign';
            t.points = routers[key].routers;
            t.stops = routers[key].routers.length;
            t.name = OBJECT.routersNameMap[key];
            t.lbs = this.calcLbs(routers[key].routers);
            t.distance = distanceAndTime.distance;
            t.time     =distanceAndTime.time
            t.routerBg = OBJECT.routersBgColorMap[key];
            t.routerId = key;
            data.push(t);
            this.caleOverWorkTime( key, t.time);
        }
        return data;
    }

    /**
     * 计算是否超过了工作时间，如果超出了工作时间把routerId 写进去每个Router异常信息变量（exceptionRouter）
     * @param routerId
     * @param time
     */
    caleOverWorkTime( routerId , time)
    {
        let driver = Driver.getInstance().getDriverByRouterId(routerId);
        if(driver)
        {
            let workTime = driver.work_hours || 0;
            if( workTime <= time)
            {
                OBJECT.exceptionRouter.add(routerId);
            }
        }

    }

    /**
     * 计算路线的总磅数
     * @param points
     * @returns {number}
     */
    calcLbs( points ) {
          let lbs = 0;
          points.forEach( function ( value ) {
               lbs = lbs+ value.GrossWeight;
          })
        return lbs.toFixed(2);
    }

    /**
     * 计算路线的距离和时间
     * @param routerId
     * @returns {{distance: string, time: string}}
     */
    calcDistanceAndTimes( routerId ){
        if(!OBJECT.routerPonits[routerId])
        {
            return false;
        }
        let schedule = OBJECT.routerPonits[routerId].schedule;
        let points = OBJECT.routerPonits[routerId].points;
        let distance = 0;
        let time = 0;
        schedule.forEach( function ( value,index ) {
             if( index >= 1)
             {
                 let d = value.distance.value / 1610 ;
                 let t = value.duration.value /60 / 60 ;
                 distance  = distance + Number(d);
                 time = time + Number(t);  //实际时间
                 time = time + (getMinuteFromStringDate(points[index-1].TimeOnSite) / 60);
             }
        })
        return {distance:distance.toFixed(2),time: time.toFixed(2) }
    }

    /**
     * 计算单条路线的超时的站点
     * @param data
     * @returns {number}
     */
    countDelayPointsOnRoute( data )
    {
        let count=0;
        for( let i=0;i<data.length;i++ )
        {
            if(data[i].delay)
            {
                count++;
            }
        }
       return count;
    }

    /**
     * 显示路线的站点详细信息
     * @param routerId
     */
    showRoutePoints( routerId ,driver) {
        let _this = this;
        if( this.allRequestIsSuccess() )
        {
          //  console.log(888)
            if(!OBJECT.routerPonits[routerId])
            {
                return null;
            }
            Router.getInstance().setCurrentRouterId( routerId );
            let departrueTime = this.getDriverDepartureTime( routerId );
            if( departrueTime == null )
            {
                $.Pro('Driver Not Found!')
                return false;
            }
            showLoading();
            let arr = OBJECT.routerPonits[routerId];
            let data=[];
            if(!arr.schedule){
                setTimeout(()=>{
                    this.showRoutePoints( routerId, driver);
                },1000)
                return false;
            }
            arr.points.forEach( function ( value ,index ) {

                let o ={};
                o.Address = value.Address;
                o.ScheduleID = value.ScheduleID || '--'
                o.ScheduleTime = value.ScheduleTime || '--';
                o.lbs    = value.GrossWeight;
                o.CustomerTag = value.CustomerTag;
                let schedule = arr.schedule[index];
                let waitTime = getMinuteFromStringDate( value.TimeOnSite )
                let duration = schedule.duration.value / 60 ;
                duration = Math.ceil(duration) + Math.ceil(waitTime) ;
                o.distance = schedule.distance.text;
                o.minute = schedule.duration.text
                o.arriveTime = increaMinuteFromStringDate( departrueTime , duration);                                            //加上路程的时间和停留时间
                o.delay = false;
                if( !isBetweenStringTime( o.ScheduleTime , o.arriveTime) )
                {
                    o.delay =  true;
                }
                departrueTime = o.arriveTime;
                data.push(o)
            })
            let source=$('#route-points-list-template').html();
            let template = Handlebars.compile(source);
            $('#route-points-list').html(template({data:data,driver:driver}));
            this.addListenerToTable();
            //colseLoading();
        }else{
            setTimeout(()=>{
                this.showRoutePoints(routerId ,driver);
            },1000)
        }
    }

    /**
     * 计算最优路线
     * @param data
     * @returns {*}
     */
    optimizeOrderpoints(data , routerId, driver ,countTime )
    {

        OBJECT.routerPonits[routerId].points.sort(function (a, b) {
            return SortByProps(a, b, { "arriveStartTimeString": "ascending", "arriveEndTimeString": "ascending" });
        });
         Router.getInstance().calculateRoute( OBJECT.routerPonits[routerId].points , routerId , OBJECT.routersBgColorMap[routerId] );
        this.showRoutePoints( routerId , driver ,2 );
    }
    /**
     * 统计迟到的数量
     */
    countDelayPoints()
    {
        CONFIG.delayPointsCounter=0;
        OBJECT.exceptionRouter = new Set()
        for(let routerId in OBJECT.routerPonits )
        {

            let weight =0;
            let departrueTime = this.getDriverDepartureTime( routerId );
            if(typeof OBJECT.routerPonits[routerId].points =='undefined')
            {
                continue;
            }
            if( departrueTime == null)
            {
               continue;
            }
            let arr = OBJECT.routerPonits[routerId];
            if(!arr.schedule){
                continue;
            }
            arr.points.forEach( function ( value ,index ) {

                    let count = false;
                    let o ={};
                    o.ScheduleTime = value.ScheduleTime || '--';
                    let schedule = arr.schedule[index];
                    let waitTime = getMinuteFromStringDate( value.TimeOnSite )
                    let duration = schedule.duration.value / 60 ;
                    duration = Math.ceil(duration) + Math.ceil(waitTime) ;
                    weight = weight + o.weight;
                    //计算是否在最大磅数和最小磅数范围
                    let maxAndminWeight = this.getMaxAndMinWeight(routerId);
                    if( weight < maxAndminWeight.min_weight || weight > maxAndminWeight )
                    {
                        OBJECT.exceptionRouter.add( routerId );
                    }
                    o.arriveTime = increaMinuteFromStringDate( departrueTime , duration);
                    if( !isBetweenStringTime( o.ScheduleTime , o.arriveTime) )
                    {
                       CONFIG.delayPointsCounter++;
                       OBJECT.exceptionRouter.add( routerId );
                    }
                    departrueTime = o.arriveTime;

            },this)
        }


    }

    /**
     * 获取司机的出发时间
     * @param routerId
     */
    getDriverDepartureTime(routerId)
    {
        if(!OBJECT.routerPonits[routerId])
        {
            return null;
        }
        let driverId = this.getDriverId(routerId);
        let departure_time;
        let drivers = OBJECT.driverList;
        if(!driverId)
        {
           return null;
        }
        drivers.forEach( function ( value ) {
               if( value.driver_id == driverId ) {
                   departure_time = value.departure_time;    //在foreach直接return 无效
               }
        })
        return departure_time;

    }
    /**
     * 获取车辆的最大磅数和最小磅数
     * @param routerId
     */
    getMaxAndMinWeight(routerId)
    {
        let ret ={}
        if(!OBJECT.routerPonits[routerId])
        {
            return null;
        }
        let vehicleId = OBJECT.routerPonits[routerId].vehicleId;
        if(!vehicleId)
        {
            return null;
        }
        OBJECT.vehicleList.forEach( function ( value ) {
            if( value.vehicle_id == vehicleId ) {
                ret = {max_weight:value.max_weight,min_weight:value.min_weight }
            }
        })
        return ret;

    }
    /**
     * 获取司机的名字
     * @param routerId
     */
    getDriverName(routerId)
    {
        if(!OBJECT.routerPonits[routerId])
        {
            return null;
        }
        let driverId = OBJECT.routerPonits[routerId].driverId;
        let nickname = null;
        let drivers =OBJECT.driverList;
        drivers.forEach( function ( value ) {
            if( value.driver_id == driverId ) {
                nickname = value.nickname;    //在foreach直接return 无效
            }
        })
        return nickname;

    }
    /**
     * 获取司机ID
     * @param routerId
     */
    getDriverId(routerId)
    {
        return OBJECT.routerPonits[routerId].driverId;
    }
    /**
     * 获取车辆的名字
     * @param routerId
     */
    getVehicleName(routerId)
    {
        if(!OBJECT.routerPonits[routerId])
        {
            return null;
        }
        let vehicleName = null;
        let vehicleId= OBJECT.routerPonits[routerId].vehicleId;
        let vehicle = OBJECT.vehicleList;
        vehicle.forEach( function ( value ) {
            if( value.vehicle_id == vehicleId ) {
                vehicleName = value.name;    //在foreach直接return 无效
            }
        })
        return vehicleName;

    }
    /**
     * 拖动顺序后重新排序站点顺序
     *
     * @returns {boolean}
     */
    reOrderRoutePoints () {
          let routerId = Router.getInstance().getCurrentRouterId();
          if(!routerId) {
              return false;
          }
          let orders = $('#route-points-list-body tr.route-points-info');
          let oldOrders = OBJECT.routerPonits[routerId].points;
          let newOrders=[];
          $.each( orders , function ( index , value ){
              let k = $(value).data('key');
              newOrders.push( oldOrders[k] );
          })

         OBJECT.routerPonits[routerId].points = newOrders;
         // console.log(OBJECT.routerPonits[routerId].points)
         Router.getInstance().calculateRouterInfo( routerId , false);

    }

    /**
     *给列表添加拖动监听事件
     */
    addListenerToTable (){
        let _this = this;
        let a = $("#table-sort").tableDnD({
            scrollAmount:10,
            onDragClass:'highlight',
            onDrop: function(table,row) {
                clearTimeout(CONFIG.updateRouterPointsTimeInterval);
                assignRoute.getInstance().reOrderRoutePoints();
                let routerId = Router.getInstance().getCurrentRouterId();

                CONFIG.optimizeOrderpoints[routerId] = false;
                    _this.showRoutePoints( routerId , assignRoute.getInstance().getDriverName( routerId ));
                //设置路线的更改状态为false
                    OBJECT.routerPonits[routerId].UpdateStatus = false;
            },
        });
    }

    /**
     * 是否所有的Route请求完成
     */
   allRequestIsSuccess()
   {
        let ret = true;
        OBJECT.requestRouteStatus.forEach( function ( value ,index) {
              if( value!='success' )
              {
                  ret = false;
              }
        })
       return ret;
   }

}